#ifndef __SGL_DRAW_H__
#define __SGL_DRAW_H__

#include <stdint.h>
#include "../sgl.h"


#define SGL_DRAW_BUFFER_SIZE    (SGL_CONFIG_PANEL_XRES * SGL_CONFIG_DRAW_BUFFER_LINE)


sgl_color_t sgl_color_mixer(sgl_color_t fg_color, sgl_color_t bg_color, uint8_t factor);
void sgl_draw_point(sgl_surf_t *surf, int16_t x, int16_t y, sgl_color_t color);
void sgl_draw_hline(sgl_surf_t *surf, int16_t x, int16_t y, int16_t len, sgl_color_t color);
void sgl_draw_vline(sgl_surf_t *surf, int16_t x, int16_t y, int16_t len, sgl_color_t color);
void sgl_draw_area_color(sgl_surf_t *surf, int16_t x1, int16_t y1, int16_t x2, int16_t y2, const sgl_color_t color);
void sgl_draw_buffer_clear(sgl_surf_t *surf, sgl_color_t color);
void sgl_draw_obj_buffer_clear(sgl_surf_t *surf, sgl_obj_t *obj, sgl_color_t color);
void sgl_draw_buffer_flush(sgl_surf_t *surf, int16_t x, int16_t y);
void sgl_draw_area_flush(sgl_rect_t rect, sgl_color_t *src);
void sgl_draw_buffer_flush_hclip(sgl_surf_t *surf, int16_t x, int16_t y, int16_t clip_start, int16_t clip_end);
sgl_surf_t* sgl_draw_get_active_surf(sgl_obj_t *obj);
void sgl_draw_set_active_surf(sgl_color_t *fb, int16_t width, int16_t height);
void sgl_draw_set_active_surf_size(int16_t width, int16_t height);

int sgl_figure_circle_path(int16_t r, int16_t* path);
sgl_pos_t sgl_figure_arc_endpoint(int16_t r, int16_t deg);
int sgl_text_width(sgl_font_t *font, const char* text);
int sgl_text_height(sgl_font_t *font);
void sgl_draw_handler(sgl_obj_t *obj);


//#define  sgl_draw_obj_surf  sgl_draw_get_active_surf(obj)


//render left top
#define SGL_RENDER_ROUND_EDGE_LT(surf, cx, cy, x, y, color) \
sgl_draw_point(surf, cx-y, cy-x, color); \
sgl_draw_point(surf, cx-x, cy-y, color);

//render right top
#define SGL_RENDER_ROUND_EDGE_RT(surf, cx, cy, x, y, color) \
sgl_draw_point(surf, cx+y-1, cy-x, color); \
sgl_draw_point(surf, cx+x-1, cy-y, color);

//render left bottom
#define SGL_RENDER_ROUND_EDGE_LB(surf, cx, cy, x, y, color) \
sgl_draw_point(surf, cx-y, cy+x-1, color); \
sgl_draw_point(surf, cx-x, cy+y-1, color);

//render right bottom
#define SGL_RENDER_ROUND_EDGE_RB(surf, cx, cy, x, y, color) \
sgl_draw_point(surf, cx+y-1, cy+x-1, color);  \
sgl_draw_point(surf, cx+x-1, cy+y-1, color);


//render left top internal
#define SGL_RENDER_ROUND_EDGE_LTI(surf, cx, cy, x, y, color) \
sgl_draw_point(surf, cx-y, cy-x+1, color); \
sgl_draw_point(surf, cx-x+1, cy-y, color);

//render right top internal
#define SGL_RENDER_ROUND_EDGE_RTI(surf, cx, cy, x, y, color) \
sgl_draw_point(surf, cx+y-1, cy-x+1, color);  \
sgl_draw_point(surf, cx+x-2, cy-y, color); 

//render left bottom internal
#define SGL_RENDER_ROUND_EDGE_LBI(surf, cx, cy, x, y, color) \
sgl_draw_point(surf, cx-y, cy+x-2, color);  \
sgl_draw_point(surf, cx-x+1, cy+y-1, color);

//render right bottom internal
#define SGL_RENDER_ROUND_EDGE_RBI(surf, cx, cy, x, y, color) \
sgl_draw_point(surf, cx+y-1, cy+x-2, color);  \
sgl_draw_point(surf, cx+x-2, cy+y-1, color);


#if SGL_CONFIG_DRAW_BUFFER_LINE == SGL_CONFIG_PANEL_YRES
#define SGL_FULL_FRAMEBUFFER
#endif

#ifdef SGL_FULL_FRAMEBUFFER
#define sgl_draw_obj_selected(obj, surf, rect) \
if(obj->selected) { \
    rect.x1 = obj->pos.x; \
    rect.y1 = obj->pos.y; \
    rect.x2 = obj->pos.x + obj->size.w - 1; \
    rect.y2 = obj->pos.y + obj->size.h - 1; \
    sgl_draw_rect_hollow(surf, rect, obj->style.body_color); \
}

#define sgl_widget_draw_buffer_flush(obj, surf)
#define sgl_widget_draw_ofs_x(pos_x)  ((pos_x) + obj->pos.x)
#define sgl_widget_draw_ofs_y(pos_y)  ((pos_y) + obj->pos.y)


#define sgl_widget_draw_rect(rect) \
sgl_rect_t rect = {.x1 = obj->pos.x, .y1 = obj->pos.y, .x2 = (int16_t)(obj->pos.x + obj->size.w), .y2 = (int16_t)(obj->pos.y + obj->size.h)};

#define sgl_widget_buffer_valid(obj)  {if(!sgl_obj_draw_valid(obj)) return;}

#else
#define sgl_draw_obj_selected(obj, surf, rect) \
if(obj->selected) { \
    rect.x1 = 0; \
    rect.y1 = 0; \
    rect.x2 = obj->size.w - 1; \
    rect.y2 = obj->size.h - 1; \
    sgl_draw_rect_hollow(surf, rect, obj->style.body_color); \
}

#define sgl_widget_draw_buffer_flush(obj, surf)  sgl_draw_buffer_flush(surf, obj->pos.x, obj->pos.y);
#define sgl_widget_draw_ofs_x(x)  (x)
#define sgl_widget_draw_ofs_y(y)  (y)


#define sgl_widget_draw_rect(rect) \
sgl_rect_t rect = {.x1 = 0, .y1 = 0, .x2 = obj->size.w, .y2 = obj->size.h};

#define sgl_widget_buffer_valid(obj) {}
#endif

#endif //__SGL_DRAW_H__
